/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pa165.ddtroops.serviceclasses;

import cz.muni.fi.pa165.ddtroops.daointerfaces.HeroDAO;
import cz.muni.fi.pa165.ddtroops.dto.DTOFactory;
import cz.muni.fi.pa165.ddtroops.dto.HeroDTO;
import cz.muni.fi.pa165.ddtroops.dto.RaceDTO;
import cz.muni.fi.pa165.ddtroops.dto.UserDTO;
import cz.muni.fi.pa165.ddtroops.entities.EntityBuilder;
import cz.muni.fi.pa165.ddtroops.entities.Gender;
import cz.muni.fi.pa165.ddtroops.entities.Hero;
import cz.muni.fi.pa165.ddtroops.entities.Race;
import cz.muni.fi.pa165.ddtroops.entities.User;
import cz.muni.fi.pa165.ddtroops.serviceinterfaces.HeroService;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author Erik
 */
@Service
@Qualifier("heroService")
public class HeroServiceImpl implements HeroService {
    @Autowired(required=true)
    private HeroDAO dao;

    public void setDao(HeroDAO dao) {
        this.dao = dao;
    }
    
    @Transactional
    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    public HeroDTO createNewHero(Gender gender, String belief, String profession,
            RaceDTO raceDTO, Byte strength, Byte dexterity, Byte constitution,
            Byte intelligence, Byte wisdom, Byte charisma)
    {
        Race race = DTOFactory.createRace(raceDTO);
        if(race == null || race.getStrength() == null || race.getDexterity() == null ||
                race.getConstitution() == null || race.getIntelligence() == null ||
                race.getWisdom() == null || race.getCharisma() == null)
            return null;
        Hero h = new EntityBuilder<Hero>(Hero.class)
                .withProperty("Gender", gender)
                .withProperty("Biography", "")
                .withProperty("Belief", belief)
                .withProperty("Profession", profession)
                .withProperty("Race", race)
                .withProperty("Strength", (byte)(strength + race.getStrength()))
                .withProperty("Dexterity", (byte)(dexterity + race.getDexterity()))
                .withProperty("Constitution", (byte)(constitution + race.getConstitution()))
                .withProperty("Intelligence", (byte)(intelligence + race.getIntelligence()))
                .withProperty("Wisdom", (byte)(wisdom + race.getWisdom()))
                .withProperty("Charisma", (byte)(charisma+ race.getCharisma()))
                .Build();
        if(!isValid(h)) return null;
        return DTOFactory.createHeroDTO(h);
    }

    private boolean isValid(Hero hero) {
        return ((hero.getXp() != null) &&
             hero.getName() != null && !hero.getName().isEmpty() &&
             hero.getGender() != null &&
             hero.getBelief() != null && !hero.getBelief().isEmpty() &&
             hero.getProfession() != null && !hero.getProfession().isEmpty() &&
             hero.getSkills() != null &&
             hero.getRace() != null &&
             hero.getStrength() != null &&
             hero.getDexterity() != null &&
             hero.getConstitution() != null &&
             hero.getIntelligence() != null &&
             hero.getWisdom() != null &&
             hero.getCharisma()  != null);
    }
    @Transactional
    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    public void create(HeroDTO heroDTO)
    {
        dao.create(DTOFactory.createHero(heroDTO));
    }
    @Transactional
    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    public void update(HeroDTO heroDTO)
    {
        dao.update(DTOFactory.createHero(heroDTO));
    }
    @Transactional
    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    public void delete(HeroDTO heroDTO)
    {
        dao.delete(DTOFactory.createHero(heroDTO));
    }
    @Transactional(readOnly=true)
    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    public HeroDTO getById(Long id)
    {
        Hero h = dao.getById(id);
        return (h!=null)?DTOFactory.createHeroDTO(h):null;
    }
    @Transactional(readOnly=true)
    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    public List<HeroDTO> getAll()
    {
        List<HeroDTO> heroDTOs = new ArrayList<HeroDTO>();
        for (Hero h : dao.getAll()) {
            heroDTOs.add(DTOFactory.createHeroDTO(h));
        }
        return heroDTOs;
    }

    @Transactional(readOnly=true)
    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    public UserDTO getUser(HeroDTO heroDTO) 
    {
        Hero h = dao.getById(heroDTO.getId());
        return (h!=null)?DTOFactory.createUserDTO(h.getUser()):null;
    }
}
